#include "factory.h"

command_t cmds[CMD_TYPES] = {
    {"pwd",NULL},
    {"ls",cmd_ls},
    {"cd",cmd_cd},
    {"puts",cmd_puts},
    {"gets",cmd_gets}
    //...
};



int main(int argc,char **argv)
{
    int ret = 0; //返回值检查变量
    //处理传入配置文件
    char args[5][20] ={0}; 
    read_config(CONFIG_FILENAME,args,5);
  
    printf("read config:\nip: %s\nport1: %s\nport2: %s\nthreadNum: %s\nqueueCapacity: %s\n",\
        args[0],args[1],args[2],args[3],args[4]);

    factory_t factory;      //这个工厂里的内容需要线程共享
                            //把要传递的东西全都放在结构体里面
    //初始化
    factory_init(&factory,atoi(args[3]),atoi(args[4]));
    //线程池
    factory_launch(&factory);

    //初始化网络监听
        //外层端口
    int socketFd = 0;
    tcp_init(&socketFd, args[0], args[1]);
    factory.socketFd = socketFd;
        //文件传输端口
    tcp_init(&(factory.transFd), args[0], args[2]);

    printf("tcp init ok, socketFd: %d  transFd: %d\n",socketFd,factory.transFd);

    struct sockaddr_in addrClient;
    int newClientFd = 0;
    int connectionAllow = 0;
    puserNode newUser;
    puserNode tmp;
    int epfd = factory.users.epfd;

    int readyNum = 0;
    int cmdType = 0;
    
    struct epoll_event event;
    event.events = EPOLLIN;
    event.data.fd = socketFd;
    ret = epoll_ctl(epfd, EPOLL_CTL_ADD, socketFd, &event);//注册socketFd
    ERROR_CHECK(ret, -1, "epoll_ctl");
    struct epoll_event evs[MAX_USER + 1];

    int count = 0;

    while (1)
    {
        readyNum = epoll_wait(epfd, evs, factory.users.userNum+1, -1);
        ERROR_CHECK(readyNum, -1, "epoll_wait");
        //printf("cmd_woker recv message\n");
        if(count<5)
        {
            printf("readyNum : %d\n", readyNum);
            count++;
        }
        for (int i = 0; i < readyNum; ++i) 
        {
            if(evs[i].data.fd == socketFd)
            {
                //从监听端口接受新客户
                bzero(&addrClient, sizeof(addrClient));
                socklen_t len=sizeof(addrClient);
                newClientFd = accept(socketFd, (struct sockaddr *)&addrClient,&len);
                //日志记录：用户登录 IP、 端口  ，时间
                printf("client ip=%s,client port=%d\n",inet_ntoa(addrClient.sin_addr),ntohs(addrClient.sin_port));
 
                event.data.fd = newClientFd;
                //用户登陆，核验用户信息
                newUser = NULL;
                while(1)
                {
                    if(0 == user_login(&factory,newClientFd,&newUser))
                        break;
                }

                printf("check login: username: %s userfd:%d userpath:%s\n",\
                    newUser->userName, newUser->fd, newUser->homePath);
                
                tmp = factory.users.userlink;
                //检查是否允许负载允许，并返回相应信息给客户

                pthread_mutex_lock(&factory.users.mutex);
                if(factory.users.userNum < factory.maxUsers)
                {
                    printf("im in lock! tmp: %s\n",tmp);
                    //允许进入，添加用户进用户链表，注册epoll信息
                    if(tmp)
                    {
                        while(tmp->next)
                        {
                            tmp = tmp->next;
                        }
                        tmp->next = newUser;
                    }
                    else
                    {
                        factory.users.userlink = newUser;//这个地方千万别赋值给tmp！
                    }
                    
                    factory.users.userNum += 1;
                    event.data.fd = newClientFd;
                    ret = epoll_ctl(epfd, EPOLL_CTL_ADD, newClientFd, &event); //注册
                    ERROR_CHECK(ret, -1, "epoll_ctl for newClentFd");
                    pthread_mutex_unlock(&factory.users.mutex);
                    connectionAllow = 1;
                    send(newClientFd, &connectionAllow, sizeof(int), 0);
                }
                else
                {
                    pthread_mutex_unlock(&factory.users.mutex);
                    //拒绝连接
                    printf("connect deny\n");
                    connectionAllow = 0;
                    send(newClientFd, &connectionAllow, sizeof(int), 0);
                }
            }
            else
            {
                tmp = factory.users.userlink;
                while (tmp)
                {
                    if (tmp->fd == evs[i].data.fd)
                    {
                        printf("message from :%s\n", tmp->userName);
                        recvCyc(tmp->fd, &cmdType, sizeof(int)); //接收命令
                        printf("recv cmdtype: %d aka cmd:%s\n", cmdType, cmds[cmdType].command);
                        cmds[cmdType].func(tmp,&factory); //调用相应命令处理函数
                        readyNum--;
                        break;
                    }
                    else
                    {
                        tmp = tmp->next;
                    }
                }
            }
        }
        
    }
   
    return 0;
}



void call_new_task(factory_t factory)
{
    int newFd = 0;
    ptaskNode_t pnewTask;
    pnewTask = (ptaskNode_t)calloc(sizeof(taskNode_t),1);// 出队并处理完之后记得free
            pnewTask->fd = newFd;
            pnewTask->pNext = NULL;
            //把任务放入等待队列
            pthread_mutex_lock(&(factory.que.queMutex));
            que_set(&factory.que,pnewTask);
            pthread_mutex_unlock(&(factory.que.queMutex));
            //唤醒一个子进程去取任务
            pthread_cond_signal(&factory.cond);
}